/***********************************************************************************************************************
*                                                                                                                      *
* SPLASH build system v0.1                                                                                             *
*                                                                                                                      *
* Copyright (c) 2013 Andrew D. Zonenberg                                                                               *
* All rights reserved.                                                                                                 *
*                                                                                                                      *
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the     *
* following conditions are met:                                                                                        *
*                                                                                                                      *
*    * Redistributions of source code must retain the above copyright notice, this list of conditions, and the         *
*      following disclaimer.                                                                                           *
*                                                                                                                      *
*    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the       *
*      following disclaimer in the documentation and/or other materials provided with the distribution.                *
*                                                                                                                      *
*    * Neither the name of the author nor the names of any contributors may be used to endorse or promote products     *
*      derived from this software without specific prior written permission.                                           *
*                                                                                                                      *
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
* THE AUTHORS BE HELD LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES        *
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR       *
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE       *
* POSSIBILITY OF SUCH DAMAGE.                                                                                          *
*                                                                                                                      *
***********************************************************************************************************************/

/**
	@brief Main library header file
 */

#ifndef splashcore_h
#define splashcore_h

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Platform includes

#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// libc includes

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#include <stdarg.h>
#include <typeinfo>

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// libstdc++ includes

#include <string>
#include <vector>
#include <list>

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Other library includes

#include <crypto++/sha.h>

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Global functions

void DebugPrintf(int level, const char* format, ...);
void DebugPrintfHeading(int level, const char* format, ...);
void DebugPrintfSilent(int level, const char* format, ...);

std::string CanonicalizePath(std::string fname);

bool DoesFileExist(std::string fname);
bool DoesDirectoryExist(std::string fname);

std::string sha256(std::string str);
std::string sha256_file(std::string path);

std::string ShellCommand(std::string cmd, bool trimNewline = false);

std::string FindSharedLibrary(std::string libname, std::string arch);

std::string GetDirOfFile(std::string fname);
std::string GetBasenameOfFile(std::string fname);
std::string GetBasenameOfFileWithoutExt(std::string fname);

std::string GetRelativePathOfFile(std::string dir, std::string fname);

void FindFilesByExtension(std::string dir, std::string ext, std::vector<std::string>& files);

__attribute__((noreturn)) void FatalError(const char* format, ...);
__attribute__((noreturn)) void FatalError(std::string str);

void FlushDirectoryAttributeCacheForFile(std::string fname);

double GetTime();

void MakeDirectoryRecursive(std::string path, int mode);

std::string str_replace(const std::string& search, const std::string& replace, std::string subject);

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Global data

extern int g_debugVerbosity;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// General / global class declarations

#include "../splash-antikernel/AntikernelModuleInfo.h"

#include "Cluster.h"
#include "SlurmCluster.h"

#include "BuildGraphNode.h"
#include "BuildGraph.h"

#include "CodeGenScriptNode.h"

#include "ToolFlags.h"

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// C++ node / toolchain classes

#include "CppToolchain.h"
#include "GnuCppToolchain.h"

#include "CppSourceNode.h"
#include "CppObjectNode.h"
#include "CppExecutableNode.h"
#include "CppSharedLibraryNode.h"
#include "CppStaticLibraryNode.h"

#include "CppGeneratedSourceNode.h"
#include "CppConfigHeaderNode.h"
#include "ConstgenNode.h"
#include "CppSvnVersionNode.h"

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// FPGA node / toolchain classes

#include "FPGAToolchain.h"
#include "XilinxFPGAToolchain.h"

#include "YosysCrowbarFPGAToolchain.h"

#include "HDLSourceNode.h"
#include "VerilogSourceNode.h"
#include "VerilogGeneratedSourceNode.h"

#include "Nocgenv2GeneratedSourceNode.h"
#include "NocgenNode.h"
#include "NocgenPLL.h"
#include "NocgenLA.h"
#include "NocgenSniffer.h"

#include "HDLNetlistNode.h"
#include "ISimSimulationNode.h"
#include "NGCNetlistNode.h"
#include "NGDNetlistNode.h"
#include "UnroutedNCDNetlistNode.h"
#include "RoutedNCDNetlistNode.h"
#include "FPGAStaticTimingAnalysisNode.h"
#include "FPGABitstreamNode.h"
#include "VM6NetlistNode.h"
#include "CPLDBitstreamNode.h"

#include "RTLILNetlistNode.h"

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Unit test classes

#include "UnitTestNode.h"
#include "FPGAUnitTestNode.h"
#include "YosysProofUnitTestNode.h"

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Binary file manipulation helpers

#include "BinaryFirmwareNode.h"
#include "HexFirmwareNode.h"
#include "MultiFileROMImage.h"
#include "SignedFirmwareNode.h"

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// More global helpers

void CreateCflagsForPackage(CppCompileFlagList& flaglist, std::string package_name);
int gcd(int a, int b);

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Export helpers

#define SPLASHFILE_EXPORT extern "C" __attribute__ ((visibility ("default")))

typedef void (* UpdateBuildGraphProc)(BuildGraph*);

//implemented in Splashfile's
SPLASHFILE_EXPORT void CreateNodes(BuildGraph* graph);
SPLASHFILE_EXPORT void CreateEdges(BuildGraph* graph);

#endif
